package com.yeyks.controller.other;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yeyks.account.dal.dao.AccountInfoMapper;
import com.yeyks.account.dal.domain.AccountInfo;
import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.constants.AccountType;
import com.yeyks.common.em.ResponseStatus;
import com.yeyks.common.exception.PermissionInvalidException;
import com.yeyks.common.exception.TokenInvalidException;
import com.yeyks.common.utils.webutil.Utility;
import com.yeyks.commonReference.append.app.OssService;
import com.yeyks.commonReference.service.account.AccountInfoService;
import com.yeyks.config.dal.dao.DocInfoMapper;
import com.yeyks.config.dal.domain.DocInfo;
import com.yeyks.consumer.dal.dao.ShareLogMapper;
import com.yeyks.consumer.dal.dao.UserCouponInfoMapper;
import com.yeyks.other.dal.dao.CouponInfoMapper;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@Api(tags = "文档模块")
@RestController
@Slf4j
@RequestMapping("/ajax")
public class UtilityController {
    @Autowired
    AccountInfoService accountService;
    @Autowired
    OssService ossService;
    @Autowired
    AccountInfoMapper accountInfoMapper;

    @Autowired
    DocInfoMapper docInfoMapper;

    @Autowired
    ShareLogMapper shareLogMapper;

    @Autowired
    CouponInfoMapper couponInfoMapper;

    @Autowired
    UserCouponInfoMapper userCouponInfoMapper;

    /**
     * 设置文档
     *
     * @param token
     * @param catalog
     * @param title
     * @param content
     * @return
     */
    @RequestMapping(value = "/utility/setDoc", method = RequestMethod.POST)
    public ResponseEntity<?> setDoc(
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "catalog", defaultValue = "", required = true) String catalog,
            @RequestParam(name = "title", defaultValue = "", required = true) String title,
            @RequestParam(name = "content", defaultValue = "", required = true) String content
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            AccountInfo accountInfo = accountService.token2AccountInfo(token);

            String ossKey = "User/" + accountInfo.getId().toString() + "/doc/" + catalog + "/" + title;

            if (!ossService.writeOSS(content.getBytes("UTF-8"), ossKey)) {
                responseBody.setCode(ResponseStatus.RS_FAIL_OSS_ENGINE.getCode());
                responseBody.setMsg(ResponseStatus.RS_FAIL_OSS_ENGINE.getMsg());
                return ResponseEntity.ok(responseBody);
            }

            accountInfo.setExtraInfo(Utility.addExtraInfoMap(accountInfo.getExtraInfo(), "doc." + catalog, title, ossKey));
            int rec = accountInfoMapper.updateExtraInfoById(accountInfo.getId(), accountInfo.getExtraInfo());

            if (rec == 0) {
                throw new Exception("updated 0 row.");
            }

            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (TokenInvalidException e) {
            responseBody.setCode(ResponseStatus.RS_FAIL_INVALID_TOKEN.getCode());
            responseBody.setMsg(ResponseStatus.RS_FAIL_INVALID_TOKEN.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

    /**
     * 获取文档
     *
     * @param id
     * @param token
     * @param catalog
     * @param title
     * @return
     */
    @RequestMapping(value = "/utility/getDoc", method = RequestMethod.POST)
    public ResponseEntity<?> getDoc(
            @RequestParam(name = "id", defaultValue = "", required = true) Integer id,
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "catalog", defaultValue = "", required = true) String catalog,
            @RequestParam(name = "title", defaultValue = "", required = true) String title
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            if (id == null || id == 0) {
                if (token != null && !token.isEmpty()) {
                    id = accountService.token2UserId(token);
                } else {
                    List<AccountInfo> accountInfoList = accountInfoMapper.selectByType(AccountType.Administrator);
                    if (accountInfoList.isEmpty()) {
                        throw new Exception("no admin account.");
                    }
                    id = accountInfoList.get(0).getId();
                }
            }

            String ossKey = "User/" + id.toString() + "/doc/" + catalog + "/" + title;
            byte[] byContent = ossService.readOSS(ossKey);
            String content = new String(byContent, "UTF-8");

            responseBody.setBody(content);
            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (TokenInvalidException e) {
            responseBody.setCode(ResponseStatus.RS_FAIL_INVALID_TOKEN.getCode());
            responseBody.setMsg(ResponseStatus.RS_FAIL_INVALID_TOKEN.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

    /**
     * 查看文档列表（从账号）
     *
     * @param id
     * @param token
     * @param catalog
     * @return
     */
    @RequestMapping(value = "/utility/listDoc", method = RequestMethod.POST)
    public ResponseEntity<?> listDoc(
            @RequestParam(name = "id", defaultValue = "", required = true) Integer id,
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "catalog", defaultValue = "", required = true) String catalog
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            AccountInfo accountInfo = null;
            if (id == null || id == 0) {
                if (token != null && !token.isEmpty()) {
                    accountInfo = accountService.token2AccountInfo(token);
                } else {
                    List<AccountInfo> accountInfoList = accountInfoMapper.selectByType(AccountType.Administrator);
                    if (accountInfoList.isEmpty()) {
                        throw new Exception("no admin account.");
                    }
                    accountInfo = accountInfoList.get(0);
                }
            }

            JSONObject jsonObject = (JSONObject) JSON.parse(accountInfo.getExtraInfo());
            JSONObject cataObject = (JSONObject) jsonObject.get("doc." + catalog);

            List<String> titles = new ArrayList<>();
            for (String key : cataObject.keySet()) {
                titles.add(key);
            }

            responseBody.setBody(titles);
            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

    @RequestMapping(value = "/utility/doc/add", method = RequestMethod.POST)
    public ResponseEntity<?> docAdd(
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "id", defaultValue = "0", required = true) Integer id,
            @RequestParam(name = "caption", defaultValue = "false", required = true) String caption,
            @RequestParam(name = "content", defaultValue = "false", required = true) String content,
            @RequestParam(name = "parent", defaultValue = "0", required = true) Integer parent
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            AccountInfo accountInfo = accountService.token2AccountInfo(token);
            if (accountInfo.getType() != AccountType.Administrator &&
                    accountInfo.getType() != AccountType.ProvinceManager &&
                    accountInfo.getType() != AccountType.CityAgent) {
                throw new PermissionInvalidException();
            }

            List<DocInfo> origInfos = docInfoMapper.selectByCaption(caption);
            if (origInfos != null && origInfos.size() != 0 && id != origInfos.get(0).getId()) {
                throw new Exception("该标题已经存在");
            }

            DocInfo docInfo = new DocInfo();
            docInfo.setCaption(caption);
            docInfo.setContent(content);
            if (parent == 0) {
                docInfo.setDirectory(true);
            } else {
                DocInfo info = docInfoMapper.selectByPrimaryKey(parent);
                if (info == null || !info.getDirectory()) {
                    throw new Exception("parent is not directory");
                }
                docInfo.setParent(parent);
                docInfo.setDirectory(false);
            }

            int rec = 0;

            if (id == 0) {

                rec = docInfoMapper.insertReturnId(docInfo);
            } else {
                docInfo.setId(id);
                rec = docInfoMapper.updateCaptionContent(docInfo);
            }

            if (rec == 0) {
                throw new Exception("insert 0 row.");
            }

            responseBody.setBody(docInfo);
            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

    /**
     * 获取文档列表
     *
     * @param parent
     * @param keyword
     * @param pageNum
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/utility/doc/list", method = RequestMethod.POST)
    public ResponseEntity<?> docList(
            @RequestParam(name = "parent", defaultValue = "0") Integer parent,
            @RequestParam(name = "keyword", defaultValue = "") String keyword,
            @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize
    ) {
        AjaxResponseBody<Map> responseBody = AjaxResponseBody.getMapAjaxResponseBody();

        try {
            Integer offset = null, maxrow = pageSize;

            if (pageNum != null && pageSize != null) {
                offset = (pageNum - 1) * pageSize;
            }

            List<Map> docInfoList;
            int count;
            if (parent == 0) {
                docInfoList = docInfoMapper.selectByDirectorKeyword(true, keyword, offset, maxrow);
                count = docInfoMapper.selectByDirectorKeywordCount(true, keyword);

            } else if (parent == -1) {
                docInfoList = docInfoMapper.selectByDirectorKeyword(false, keyword, offset, maxrow);
                count = docInfoMapper.selectByDirectorKeywordCount(false, keyword);
            } else {
                docInfoList = docInfoMapper.selectByParentKeyword(parent, keyword, offset, maxrow);
                count = docInfoMapper.selectByParentKeywordCount(parent, keyword);
            }

            responseBody.getBody().put("list", docInfoList);
            responseBody.getBody().put("count", count);

            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

    /**
     * 文档删除
     *
     * @param token
     * @param id
     * @return
     */
    @RequestMapping(value = "/utility/doc/del", method = RequestMethod.POST)
    public ResponseEntity<?> docDel(
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "id", defaultValue = "", required = true) Integer id
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            AccountInfo accountInfo = accountService.token2AccountInfo(token);
            if (accountInfo.getType() != AccountType.Administrator &&
                    accountInfo.getType() != AccountType.ProvinceManager &&
                    accountInfo.getType() != AccountType.CityAgent) {
                throw new PermissionInvalidException();
            }

            if (id == null || id == 0) {
                throw new Exception("id eq 0");
            }

            int rec = docInfoMapper.deleteById(id);
            if (rec == 0) {
                throw new Exception("insert 0 row.");
            }

            responseBody.setBody(rec);
            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }

//    /**
//     * 设置抽成比例
//     *
//     * @param token
//     * @param admin
//     * @param branch
//     * @param city
//     * @return
//     */
//    @RequestMapping(value = "/utility/precentage/set", method = {RequestMethod.POST, RequestMethod.GET})
//    public ResponseEntity<?> precentageSet(
//            @RequestParam(name = "token", defaultValue = "", required = true) String token,
//            @RequestParam(name = "admin", defaultValue = "0", required = true) Integer admin,
//            @RequestParam(name = "branch", defaultValue = "0", required = true) Integer branch,
//            @RequestParam(name = "city", defaultValue = "0", required = true) Integer city
//    ) {
//        AjaxResponseBody responseBody = new AjaxResponseBody();
//
//        try {
//            AccountInfo accountInfo = accountService.token2AccountInfo(token);
//            if (accountInfo.getType() != AccountType.Administrator) {
//                throw new PermissionInvalidException();
//            }
//
//            accountService.setPrecentage(admin, branch, city);
//
//            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
//            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
//        } catch (Throwable e) {
//            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
//            responseBody.setMsg(e.getMessage());
//        }
//
//        return ResponseEntity.ok(responseBody);
//    }

    /**
     * 获取各分享类型的数量
     *
     * @param token
     * @param gmtStart
     * @param gmtEnd
     * @return
     */
    @RequestMapping(value = "/share/countGbt", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity<?> shareCountGbt(
            @RequestParam(name = "token", defaultValue = "", required = true) String token,
            @RequestParam(name = "gmtStart", defaultValue = "", required = true) Long gmtStart,
            @RequestParam(name = "gmtEnd", defaultValue = "", required = true) Long gmtEnd
    ) {
        AjaxResponseBody responseBody = new AjaxResponseBody();

        try {
            AccountInfo accountInfo = accountService.token2AccountInfo(token);
            if (accountInfo.getType() == AccountType.User) {
                throw new PermissionInvalidException();
            }

            Date dateStart = null, dateEnd = null;
            try {
                if (gmtStart != null) {
                    dateStart = new Date(gmtStart);
                }
                if (gmtEnd != null) {
                    dateEnd = new Date(gmtEnd);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }

            List<Map> shareCounts = shareLogMapper.getCountGroupByType(
                    dateStart, dateEnd
            );

            responseBody.setBody(shareCounts);
            responseBody.setCode(ResponseStatus.RS_SUCCESS.getCode());
            responseBody.setMsg(ResponseStatus.RS_SUCCESS.getMsg());
        } catch (Throwable e) {
            responseBody.setCode(ResponseStatus.RS_FAIL.getCode());
            responseBody.setMsg(e.getMessage());
        }

        return ResponseEntity.ok(responseBody);
    }
}
